import java.awt.Color;

import junit.framework.TestCase;

/*
 * This testing framework provides basic level tests for 
 * each of the methods, however additional testing will be 
 * required, along with extensive testing of ALL helper methods
 * that you write.
 */
public class PictureTest extends TestCase {
	/* A method to test getGrayValue, which is a helper method
	 * of covertToAscii. This method should be working if the
	 * darken picture returns a proper gray value. 
	 */
	public void testGetGrayValue(){
		Picture pic = Picture.loadPicture("Colleen.bmp");
		// The idea behind this test is a picture after darken(1) should have its gray
		// value lowered by 1.
		assertTrue(pic.grayscale().darken(1).getGrayValue(0,0)+1 == pic.grayscale().getGrayValue(0,0));
	}
	
	
	/*
	 * A method to test the private helper methods within
	 * Picture.java
	 */
	
	public void testHelpers()
	{
		assertTrue(Picture.helpersWork());
		
	}
	/*
	 * Validate that grayscale works and does not modify the 
	 * original Picture object.
	 */
	public void testGrayscale()
	{
		Picture pic 		= Picture.loadPicture("Creek.bmp");
		Picture picCopy 	= new Picture(pic);
		Picture picCorrect	= Picture.loadPicture("Creek_grayscale.bmp");
		Picture picTest		= pic.grayscale();
		assertTrue(pic.equals(picCopy));
		assertTrue(picCorrect.equals(picTest));
	}
	/*
	 * Validate that negate works and does not modify the 
	 * original Picture object.
	 */
	public void testNegate()
	{
		Picture pic 		= Picture.loadPicture("Creek.bmp");
		Picture picCopy 	= new Picture(pic);
		Picture picCorrect	= Picture.loadPicture("Creek_negate.bmp");
		Picture picTest		= pic.negate();
		assertTrue(pic.equals(picCopy));
		assertTrue(picCorrect.equals(picTest));
	}
	/*
	 * Validate that rotate(1) works and does not modify the 
	 * original Picture object.
	 */
	public void testRotate1()
	{
		Picture pic 		= Picture.loadPicture("CalOriginal.bmp");
		Picture picCopy 	= new Picture(pic);
		Picture picCorrect	= Picture.loadPicture("CalRotate1.bmp");
		Picture picTest		= pic.rotate(1);
		assertTrue(pic.equals(picCopy));
		assertTrue(picCorrect.equals(picTest));
	}

	/*
	 * Validate that rotate(2) works and does not modify the 
	 * original Picture object.
	 */
	public void testRotate2()
	{
		Picture pic 		= Picture.loadPicture("CalOriginal.bmp");
		Picture picCopy 	= new Picture(pic);
		Picture picCorrect	= Picture.loadPicture("CalRotate2.bmp");
		Picture picTest		= pic.rotate(2);
		assertTrue(pic.equals(picCopy));
		assertTrue(picCorrect.equals(picTest));
	}

	/*
	 * Validate that rotate(3) works and does not modify the 
	 * original Picture object.
	 */
	public void testRotate3()
	{
		Picture pic 		= Picture.loadPicture("CalOriginal.bmp");
		Picture picCopy 	= new Picture(pic);
		Picture picCorrect	= Picture.loadPicture("CalRotate3.bmp");
		Picture picTest		= pic.rotate(3);
		assertTrue(pic.equals(picCopy));
		assertTrue(picCorrect.equals(picTest));
	}
	
	
	public void testRotateAll() {
		Picture pic 	= Picture.loadPicture("CalOriginal.bmp");
		Picture picCopy = new Picture(pic);
		Picture pic90	= Picture.loadPicture("CalRotate1.bmp");
		Picture pic180  = Picture.loadPicture("CalRotate2.bmp");
		Picture pic270  = Picture.loadPicture("CalRotate3.bmp");
		Picture picTest = pic.rotate(4);
		assertTrue(pic.equals(picCopy));
		assertTrue(pic.equals(picTest));
		picTest = pic.rotate(0);
		assertTrue(pic.equals(picCopy));
		assertTrue(pic.equals(picTest));
		picTest = pic.rotate(-4);
		assertTrue(pic.equals(picCopy));
		assertTrue(pic.equals(picTest));
		picTest	= pic.rotate(-1);
		assertTrue(pic.equals(picCopy));
		assertTrue(pic270.equals(picTest));
		picTest	= pic.rotate(-2);
		assertTrue(pic.equals(picCopy));
		assertTrue(pic180.equals(picTest));
		picTest	= pic.rotate(-5);
		assertTrue(pic.equals(picCopy));
		assertTrue(pic270.equals(picTest));
		picTest	= pic.rotate(5);
		assertTrue(pic.equals(picCopy));
		assertTrue(pic90.equals(picTest));
		picTest	= pic.rotate(22);
		assertTrue(pic.equals(picCopy));
		assertTrue(pic180.equals(picTest));
	}
	/*
	 * Validate that flip(Picture.HORIZONTAL) works and does not modify the 
	 * original Picture object.
	 */
	public void testFlipHorixontal()
	{
		Picture pic 		= Picture.loadPicture("CalOriginal.bmp");
		Picture picCopy 	= new Picture(pic);
		Picture picCorrect	= Picture.loadPicture("CalHorizontal.bmp");
		Picture picTest		= pic.flip(Picture.HORIZONTAL);
		assertTrue(pic.equals(picCopy));
		assertTrue(picCorrect.equals(picTest));
	}
	/*
	 * Validate that flip(Picture.VERTICAL) works and does not modify the 
	 * original Picture object.
	 */
	public void testFlipVertical()
	{
		Picture pic 		= Picture.loadPicture("CalOriginal.bmp");
		Picture picCopy 	= new Picture(pic);
		Picture picCorrect	= Picture.loadPicture("CalVertical.bmp");
		Picture picTest		= pic.flip(Picture.VERTICAL);
		assertTrue(pic.equals(picCopy));
		assertTrue(picCorrect.equals(picTest));
	}
	/*
	 * Validate that flip(Picture.FORWARD_DIAGONAL) works and 
	 * does not modify the original Picture object.
	 */
	public void testFlipForwardDiagonal()
	{
		Picture pic 		= Picture.loadPicture("CalOriginal.bmp");
		Picture picCopy 	= new Picture(pic);
		Picture picCorrect	= Picture.loadPicture("CalForwardDiagonal.bmp");
		Picture picTest		= pic.flip(Picture.FORWARD_DIAGONAL);
		assertTrue(pic.equals(picCopy));
		assertTrue(picCorrect.equals(picTest));
	}
	/*
	 * Validate that flip(Picture.BACKWARD_DIAGONAL) works and 
	 * does not modify the original Picture object.
	 */
	public void testFlipBackwardDiagonal()
	{
		Picture pic 		= Picture.loadPicture("CalOriginal.bmp");
		Picture picCopy 	= new Picture(pic);
		Picture picCorrect	= Picture.loadPicture("CalBackwardDiagonal.bmp");
		Picture picTest		= pic.flip(Picture.BACKWARD_DIAGONAL);
		assertTrue(pic.equals(picCopy));
		assertTrue(picCorrect.equals(picTest));
	}
	/*
	 * Validate that blur works and does not modify the 
	 * original Picture object.
	 */
	public void testBlur()
	{
		Picture pic 		= Picture.loadPicture("Creek.bmp");
		Picture picCopy 	= new Picture(pic);
		Picture picCorrect	= Picture.loadPicture("Creek_blur.bmp");
		Picture picTest		= pic.blur(3);
		// Test if each pixel is assigned with correct values
		for (int x=0;x<pic.getWidth();x++){
			for (int y=0;y<pic.getHeight();y++){
				if (!(picTest.getPixel(x, y).getAlpha()==picCorrect.getPixel(x, y).getAlpha())){
					System.out.println(x+" "+y+" "+"alpha");
				}
				if (!(picTest.getPixel(x, y).getRed()==picCorrect.getPixel(x, y).getRed())){
					System.out.println(x+" "+y+" "+"red");
				}
				if (!(picTest.getPixel(x, y).getBlue()==picCorrect.getPixel(x, y).getBlue())){
					System.out.println(x+" "+y+" "+"blue");
				}
				if (!(picTest.getPixel(x, y).getGreen()==picCorrect.getPixel(x, y).getGreen())){
					System.out.println(x+" "+y+" "+"green");
				}
			}
		}
		assertTrue(pic.equals(picCopy));
		assertTrue(picCorrect.equals(picTest));

	}
	/*
	 * Validate that showEdges works and does not modify the 
	 * original Picture object.
	 */
	public void testShowEdges()
	{
		Picture pic 		= Picture.loadPicture("Colleen.bmp");
		Picture picCopy 	= new Picture(pic);
		Picture picCorrect	= Picture.loadPicture("Colleen_showEdges.bmp");
		Picture picTest		= pic.showEdges(20);
		assertTrue(pic.equals(picCopy));
		assertTrue(picCorrect.equals(picTest));
	}
	/*
	 * Another test case of show edges
	 * In a completely darkened picture, there should be no edges
	 */
	public void testShowEdges2()
	{
		Picture pic 		= Picture.loadPicture("Creek.bmp");
		pic = pic.darken(255);
		Picture picTest		= pic.showEdges(1);
		assertTrue(picTest.equals(pic.negate()));
		

	}
	
	/*
	 * Validate that chromaKey works and does not modify the 
	 * original Picture object.
	 */
	public void testChromaKey()
	{
		Picture pic 		= Picture.loadPicture("Colleen.bmp");
		Picture bg 			= Picture.loadPicture("Creek.bmp");
		Picture picCopy 	= new Picture(pic);
		Picture picCorrect	= Picture.loadPicture("Colleen_chromaKey.bmp");
		Picture picTest		= pic.chromaKey(118, 54, bg, 30);
		assertTrue(pic.equals(picCopy));
		assertTrue(picCorrect.equals(picTest));
	}

	/*
	 * Tests the color changing a solid color:
	 * darken
	 */
	public void testColorTranslationsDarker()
	{
		Picture pic = Picture.loadPicture("Gray.bmp");
		Picture darker = Picture.loadPicture("Gray_darker.bmp");
		assertTrue(darker.equals(pic.darken(30)));
			
	}
	/*
	 * Tests the color changing a solid color:
	 * lighten
	 */
	public void testColorTranslationsLighter()
	{
		Picture pic = Picture.loadPicture("Gray.bmp");
		Picture lighter = Picture.loadPicture("Gray_lighter.bmp");
		assertTrue(lighter.equals(pic.lighten(30)));
			
	}
	/*
	 * Another test of darken method and lighten method
	 * darken it to completely black and then lighten it
	 * to completely white
	 */
	public void testDarkenAndLightenExtremeCase()
	{
		Picture pic = Picture.loadPicture("Gray.bmp");
		assertTrue(pic.darken(255).equals(pic.lighten(255).negate()));
	}
	/*
	 * Tests the color changing a solid color:
	 * addGreen
	 */
	
	public void testColorTranslationsGreener()
	{
		Picture pic = Picture.loadPicture("Gray.bmp");
		Picture greener	= Picture.loadPicture("Gray_more_green.bmp");
		assertTrue(greener.equals(pic.addGreen(30)));
			
	}
	/*
	 * Tests the color changing a solid color:
	 * addBlue
	 */
	public void testColorTranslationsBluer()
	{
		Picture pic = Picture.loadPicture("Gray.bmp");
		Picture bluer = Picture.loadPicture("Gray_more_blue.bmp");
		assertTrue(bluer.equals(pic.addBlue(30)));
			
	}
	/*
	 * Tests the color changing a solid color:
	 * addRed
	 */
	public void testColorTranslationsReder()
	{
		Picture pic = Picture.loadPicture("Gray.bmp");
		Picture reder = Picture.loadPicture("Gray_more_red.bmp");
		assertTrue(reder.equals(pic.addRed(30)));	
			
	}
	/*
	 * Validate that paintBucket works and does not modify the 
	 * original Picture object.
	 */
	public void testPaintBucket()
	{
		Picture pic 		= Picture.loadPicture("Colleen.bmp");
		Picture picCopy 	= new Picture(pic);
		Picture picCorrect	= Picture.loadPicture("Colleen_paintBucket.bmp");
		Picture picTest		= pic.paintBucket(118, 54, 30, new Color(0, 255, 0));
		assertTrue(pic.equals(picCopy));
		assertTrue(picCorrect.equals(picTest));
	}
	/*
	 * Validate that convertToAscii works and does not modify the 
	 * original Picture object.
	 */
	public void testConvertToAscii()
	{
		Picture pic         = Picture.loadPicture("mickey.bmp");
		Picture picCopy     = new Picture(pic);
		Picture picCorrect  = Picture.loadPicture("mickey_ascii.bmp");
		Picture picTest     = pic.convertToAscii();
		assertTrue(pic.equals(picCopy));
		assertTrue(picCorrect.equals(picTest));
	}
	/*
	 * Validate that showEdges works and does not modify the 
	 * original Picture object (and this picture is cute)
	 */
	public void testShowEdgesMickey()
	{
		Picture pic         = Picture.loadPicture("mickey.bmp");
		Picture picCopy     = new Picture(pic);
		Picture picCorrect  = Picture.loadPicture("mickey_showEdges.bmp");
		Picture picTest     = pic.showEdges(20);
		assertTrue(pic.equals(picCopy));
		assertTrue(picCorrect.equals(picTest));
	}
	/**
	 * Helper method for loading a picture in the current directory.
	 */
}

